#include "Constantes.h"
#include "Logger.h"
#include <string.h>
#include <time.h>

using namespace std;
Logger* Logger::instance = NULL;

Logger :: Logger() {
        lockLog     = new Lock((char *)LOG_FILE);
        lockSynchro = new Lock((char *)SYNCHRO_FILE);
        lockDebug   = new Lock((char *)DEBUG_FILE);
        this->setFlags(true, true, true, true);
}

Logger* Logger :: getInstance () {

        if ( instance == NULL ){
                instance = new Logger ();
        }
        return instance;
}

void Logger :: destruir () {
        if ( instance != NULL ) {
                delete(lockLog);
                delete(lockSynchro);
                delete(lockDebug);
                delete ( instance );
                instance = NULL;
        }
}

std::string Logger::getString(int value) {
        char texto[32];
        sprintf(texto, "%d", value);
        string message = texto;
        return message;
}

std::string Logger::getTimeStamp(){
        time_t rawtime;
        struct tm * timeinfo;
        char buffer [80];

        time ( &rawtime );
        timeinfo = localtime ( &rawtime );
        strftime (buffer,80,"[%d/%m/%y %H:%M:%S]\t",timeinfo);
        std::string mensaje = buffer;

        return mensaje;
}

std::string Logger::getHeader(){
        std::string mensaje = getTimeStamp() + "(" + getString(getppid()) + ")(" + getString(getpid()) + ")\t";
        return mensaje;
}

void Logger::log(std::string evento){
        if (this->modoLog){
                std::string mensaje = getHeader() + evento + "\n";
                //Convertimos a char*
                char * mens = (char *)strdup(mensaje.c_str());
                lockLog->tomarLock ();
                lockLog->escribir(mens, mensaje.length());
                lockLog->liberarLock();
                free(mens);
        }
}

void Logger::synchro(std::string evento){
        if (this->modoSyn){
                std::string mensaje = getHeader() + evento + "\n";
                //Convertimos a char*
                char * mens = (char *)strdup(mensaje.c_str());
                lockSynchro->tomarLock();
                lockSynchro->escribir(mens, mensaje.length());
                lockSynchro->liberarLock();
                free(mens);
        }
}

void Logger::debug(std::string evento){
        if (this->modoDebug){
                std::string mensaje = getHeader() + evento + "\n";
                //Convertimos a char*
                char * mens = (char *)strdup(mensaje.c_str());
                lockDebug->tomarLock();
                lockDebug->escribir(mens, mensaje.length());
                lockDebug->liberarLock();
                free(mens);
        }
}

void Logger::print(std::string evento){
        if (this->modoCout){
                std::string mensaje = getHeader() + evento + "\n";
                cout << mensaje << endl;
        }
}

void Logger::setFlags(bool modoDebug, bool modoLog, bool modoSyn, bool modoCout){
        this->modoDebug = modoDebug;
        this->modoLog   = modoLog;
        this->modoSyn   = modoSyn;
        this->modoCout  = modoCout;
}

void Logger::loggearLog(std::string evento){
        log(evento);
        debug(evento);
        print(evento);
}

void Logger::loggearSynchro(std::string evento){
        synchro(evento);
        debug(evento);
        print(evento);
}

void Logger::loggearDebug(std::string evento){
        debug(evento);
        print(evento);
}

void Logger::loggearCout(std::string evento){
        print(evento);
}
